package cc.decat.escript.object;

import cc.decat.escript.codegen.FunctionGenerate;
import cc.decat.escript.runtime.Closure;
import cc.decat.escript.runtime.Env;

import java.util.ArrayList;
import java.util.List;

public abstract class ESFunctionObject extends ESObject {

    private String name;
    private Closure closure;
    private final List<ESFunctionObject> childFunctionObjectList;
    private FunctionGenerate functionGenerate;

    public ESFunctionObject() {
        super(null);
        this.childFunctionObjectList = new ArrayList<>();
    }

    public Closure generateClosure(List<ESObject> args) {
        Env newEnv = new Env(closure.getParentEnv(), functionGenerate.getBodyBlockGenerate().getSymbolTable());
        Closure newClosure = new Closure();
        newClosure.setParent(closure.getParent());
        newClosure.setParentEnv(closure.getParentEnv());
        newClosure.setEnv(newEnv);
        newClosure.setFunctionObject(this);
        newClosure.setArgs(args);

        for(int i = 0; i < args.size(); i++) {
            newEnv.setLocalObj(i, args.get(i));
        }

        return newClosure;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Closure getClosure() {
        return closure;
    }

    public void setClosure(Closure closure) {
        this.closure = closure;
    }

    public List<ESFunctionObject> getChildFunctionObjectList() {
        return childFunctionObjectList;
    }

    public FunctionGenerate getFunctionGenerate() {
        return functionGenerate;
    }

    public void setFunctionGenerate(FunctionGenerate functionGenerate) {
        this.functionGenerate = functionGenerate;
        for(int i = 0; i < functionGenerate.getChildFunctionGenerateList().size(); i++) {
            childFunctionObjectList.add(null);
        }
    }
}
